package com.wsfk.ssm.service.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import maps.com.wsfk.ssm.client.BillMapper;
import maps.com.wsfk.ssm.client.ClientMapper;
import maps.com.wsfk.ssm.client.ProductMapper;

import com.wsfk.ssm.entity.Bill;
import com.wsfk.ssm.entity.HandBook;
import com.wsfk.ssm.entity.Product;
import com.wsfk.ssm.entity.User;

@Service("InAppPurchaseSvcImpl")
public class InAppPurchaseSvcImpl implements InAppPurchaseSvc {

	Logger log = Logger.getLogger(this.getClass());

	private ProductMapper productMapper;
	private BillMapper billMapper;

	private ClientMapper clientMapper;

	private ClientSvc clientSvc;

	/* (non-Javadoc)
	 * @see com.wsfk.ssm.service.client.InAppPurchaseSvc#queryProduces(java.lang.String)
	 */
	@Override
	public List<Product> queryProduces(String appId) {
		List<Product> list = productMapper.selectProductsByType(appId);
		return list;
	}

	/* (non-Javadoc)
	 * @see com.wsfk.ssm.service.client.InAppPurchaseSvc#addBill(java.lang.String, java.lang.String, java.util.Date)
	 */
	@Override
	public String addBill(String in, String userid, Date now) {
		String id = UUID.randomUUID().toString();
		Bill bill = new Bill();
		bill.setTicket(in);
		bill.setUserid(userid);
		bill.setCreateDate(now);
		bill.setId(id);
		int i = billMapper.insertBill(bill);
		if(i==0){
			return null;
		}
		return id;
	}

	/* (non-Javadoc)
	 * @see com.wsfk.ssm.service.client.InAppPurchaseSvc#addOder(java.lang.String, java.util.Date, java.lang.String)
	 */
	@Override
	public Bill addOder(String json, Date now, String billid) {
		Bill bill = billMapper.getBillById(billid);
		if (bill == null) {
			log.error("not find bill " + billid + " | " + json);
			throw new RuntimeException("not find bill");
		}
		bill.setOrders(json);
		bill.setEndDate(now);
		int i = billMapper.updateBill(bill);
		if (i == 0) {
			log.error("not end bill " + billid + " | " + json);
			throw new RuntimeException("not end bill");
		}
		return bill;
	}
	/* (non-Javadoc)
	 * @see com.wsfk.ssm.service.client.InAppPurchaseSvc#verifyApple(java.lang.String, java.lang.String)
	 */
	@Override
	public boolean verifyApple(String in, String userid) {
		try {
			String billid = addBill(in, userid, new Date());
			String json = ticketCheck(in);
			Bill bill = addOder(json, new Date(), billid);
			return jsonPars(json);
		} catch (Exception e) {
			log.error("Bill no verify |"+userid+" | "+in);
			throw new RuntimeException(e);
		}
	}

	/* (non-Javadoc)
	 * @see com.wsfk.ssm.service.client.InAppPurchaseSvc#buyBook(java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public int buyBook(String userName ,String password, String bookid) {
		if(StringUtils.isNotEmpty(bookid)){
			return clientSvc.updateEndTime(bookid);
		}
		//TODO NULL
		User user = clientMapper.getUserByName(userName);
		return clientSvc.addBook(user.getId());
	}


	// 解析json、判断是否交易成功
	/* (non-Javadoc)
	 * @see com.wsfk.ssm.service.client.InAppPurchaseSvc#jsonPars(java.lang.String)
	 */
	@Override
	public boolean jsonPars(String json) {
		json = json.replaceAll("\"", "");
		json = json.replaceAll(" ", "");
		json = json.replaceAll("\\{", ",");
		json = json.replaceAll("\\}", ",");

		String[] arry = json.split(",");

		System.out.println(Arrays.toString(arry));
		List<String> list = new ArrayList<String>();
		Map<String, String> map = new HashMap<String, String>();

		for (String temp : arry) {
			if (StringUtils.isEmpty(temp)) {
				continue;
			}
			if (StringUtils.endsWith(temp, ":")) {
				continue;
			}
			if (StringUtils.contains(temp, ":")) {
				list.add(temp);
			}
		}

		for (String temp : list) {
			String[] enty = temp.split(":");
			map.put(enty[0], enty[1]);
		}
		boolean falg = false;
		String i = map.get("status");
		if (("0").equals(i)) {
			falg = true;
		}
		return falg;
	}

	/* (non-Javadoc)
	 * @see com.wsfk.ssm.service.client.InAppPurchaseSvc#ticketCheck(java.lang.String)
	 */
	@Override
	public String ticketCheck(String ticket) throws KeyManagementException,
			NoSuchAlgorithmException, MalformedURLException, ProtocolException,
			IOException {
		String order = null;
		HttpsURLConnection conn = initHttpClient();
		inputTicket(ticket, conn);
		order = outputOrder(conn);
		return order;
	}

	protected String outputOrder(HttpsURLConnection conn) throws IOException {
		String order = null;
		if (conn.getResponseCode() == 200) {
			InputStream is = conn.getInputStream();
			byte[] buf = new byte[1024];
			int len = 0;
			while ((len = is.read(buf)) > 0) {
				order = new String(buf, 0, len);
			}
			is.close();
		}
		return order;
	}

	protected void inputTicket(String src, HttpsURLConnection conn)
			throws IOException {
		String json = "{\"receipt-data\":\"" + src + "\"}";

		OutputStream os = conn.getOutputStream();
		os.write(json.getBytes());
		os.flush();
		os.close();
		conn.connect();
	}

	protected HttpsURLConnection initHttpClient()
			throws NoSuchAlgorithmException, KeyManagementException,
			MalformedURLException, IOException, ProtocolException {
		SSLContext sc = SSLContext.getInstance("SSL");

		X509TrustManager xtm = new X509TrustManager() { // 创建TrustManager
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
			}

			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
			}

			public X509Certificate[] getAcceptedIssuers() {
				return null;
			}
		};
		sc.init(null, new TrustManager[] { xtm },
				new java.security.SecureRandom());

		HostnameVerifier hvf = new HostnameVerifier() {
			public boolean verify(String hostname, SSLSession session) {
				return true;
			}
		};

		/**
		 * TODO 验证购买
		 * 沙盒测试地址：https://sandbox.itunes.apple.com/verifyReceipt
		 *    正式地址：https://buy.itunes.apple.com/verifyReceipt
		 */
		URL url = new URL("https://sandbox.itunes.apple.com/verifyReceipt");
		HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
		conn.setReadTimeout(10000);
		conn.setRequestMethod("POST");
		conn.setDoOutput(true);
		conn.setSSLSocketFactory(sc.getSocketFactory());
		conn.setHostnameVerifier(hvf);
		return conn;
	}

	public User getUserByUserName(String userName){
		User user = clientMapper.getUserByName(userName);
		return user;
	}
	@Resource
	public void setClientSvc(ClientSvc dao) {
		this.clientSvc = dao;
		
	}
	@Resource
	public void setProductMapper(ProductMapper productMapper) {
		this.productMapper = productMapper;
	}
	@Resource
	public void setBillMapper(BillMapper billMapper) {
		this.billMapper = billMapper;
	}
	@Resource
	public void setClientMapper(ClientMapper mapper) {
		this.clientMapper = mapper;
	}
}
